---
title: Umbraco 与 Astro
description: 使用 Umbraco 作为 CMS 向你的 Astro 项目添加内容
sidebar:
  label: Umbraco
type: cms
stub: false
logo: umbraco
i18nReady: true
---
import { FileTree, Steps } from '@astrojs/starlight/components';
import ReadMore from '~/components/ReadMore.astro'; 

[Umbraco CMS](https://umbraco.com/) 是一个开源的 ASP.NET Core CMS。默认情况下，Umbraco 使用 Razor 页面作为其前端，但也可以作为无头 CMS 使用。

## 与 Astro 集成

在本节中，你将使用 Umbraco 的原生 [Content Delivery API](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api) 为你的 Astro 项目提供内容。

### 前提条件

要开始，你需要具备以下条件：

1. **一个 Astro 项目** - 如果你还没有 Astro 项目，我们的 [安装指南](/zh-cn/install-and-setup/) 将帮助你快速启动和运行。
2. **一个 Umbraco（v12+）项目** - 如果你还没有 Umbraco 项目，请参阅这个 [安装指南](https://docs.umbraco.com/umbraco-cms/fundamentals/setup/install/)。

### 设置 Content Delivery API

要启用 Content Delivery API，请更新你的 Umbraco 项目的 `appsettings.json` 文件：

```json title="appsettings.json"
{
  "Umbraco": {
    "CMS": {
      "DeliveryApi": {
        "Enabled": true,
        "PublicAccess": true
      }
    }
  }
}
```

你可以根据需要配置额外的选项，如公共访问、API 密钥、允许的内容类型、会员授权等。更多信息请参见 [Umbraco Content Delivery API 文档](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api)。

### 获取数据

使用 `fetch()` 调用 Content Delivery API 来访问你的内容，并使其可用于你的 Astro 组件。

下面的示例展示了获取的文章列表，包括文章日期和内容等属性。

```astro title="src/pages/index.astro"
---
const res = await fetch('http://localhost/umbraco/delivery/api/v2/content?filter=contentType:article');
const articles = await res.json();
---
<h1>Astro + Umbraco 🚀</h1>
{
  articles.items.map((article) => (
      <h1>{article.name}</h1>
      <p>{article.properties.articleDate}</p>
      <div set:html={article.properties.content?.markup}></div>
  ))
}
```


<ReadMore>了解更多关于 [在 Astro 中获取数据](/zh-cn/guides/data-fetching/) 的信息。</ReadMore>

## 使用 Umbraco 和 Astro 构建博客

### 前提条件

- **一个 Astro 项目** - 如果你还没有 Astro 项目，我们的 [安装指南](/zh-cn/install-and-setup/) 将帮助你快速启动和运行。

- **一个启用了 Content Delivery API 的 Umbraco 项目（v12+）** - 遵循这个 [安装指南](https://docs.umbraco.com/umbraco-cms/fundamentals/setup/install/) 来创建一个新项目。

### 在 Umbraco 中创建博客文章

从 [Umbraco 后台](https://docs.umbraco.com/umbraco-cms/fundamentals/backoffice) 创建一个简单博客文章的文档类型，命名为 'Article'。

<Steps>
1. 为你的 'Article' 文档类型配置以下属性：

		- Title (DataType: Textstring)
		- Article Date (DataType: Date Picker)
		- Content (DataType: Richtext Editor)

2. 将 'Article' 文档类型的 "Allow as root" 选项设置为 `true`。

3. 在 Umbraco 后台的 "Content" 部分，[创建并发布你的第一篇博客文章](https://docs.umbraco.com/umbraco-cms/fundamentals/data/defining-content)。你可以重复这个过程多次。

</Steps>

想了解更多信息，请观看[创建文档类型的视频指南](https://www.youtube.com/watch?v=otRuIkN80qM)。

### 在 Astro 中展示博客文章列表

创建一个 `src/layouts/` 文件夹，然后添加一个新文件 `Layout.astro`，内容如下：

```astro title="src/layouts/Layout.astro"
---
---
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>My Blog with Astro and Umbraco</title>
</head>
<body>
    <main>
        <slot />
    </main>
</body>
</html>
```

你的项目现在应该包含以下文件：

<FileTree>
- src/
  - **layouts/**
    - **Layout.astro**
  - pages/
    - index.astro
</FileTree>

要创建博客文章列表，首先使用 `fetch` 调用 Content Delivery API 的 `content` 端点，并按 'article' 的 contentType 进行筛选。文章对象将包括在 CMS 中设置的属性和内容。然后，你可以遍历这些文章，并显示每个标题及其文章的链接。

将 `index.astro` 的默认内容替换为以下代码：

```astro title="src/pages/index.astro"
---
import Layout from '../layouts/Layout.astro';
const res = await fetch('http://localhost/umbraco/delivery/api/v2/content?filter=contentType:article');
const articles = await res.json();
---
<Layout>
	<h2>Blog Articles</h2>
	{
        articles.items.map((article: any) => (
            <div>
                <h3>{article.properties.title}</h3>
                <p>{article.properties.articleDate}</p>
                <a href={article.route.path}>Read more</a>
            </div>
        ))
    }
</Layout>
```

### 生成单个博客文章

在 `/pages/` 目录的根部创建文件 `[...slug].astro`。此文件将用于[动态生成单个博客页面](/zh-cn/guides/routing/#动态路由)。

请注意，生成页面 url 路径的 `params` 属性包含来自 API 获取的 `article.route.path`。同样，`props` 属性必须包含整个 `article`，以便你可以访问 CMS 条目中的所有信息。

添加以下代码到 `[...slug].astro`，它将创建你的单个博客文章页面：

```astro title="[...slug].astro"
---
import Layout from '../layouts/Layout.astro';

export async function getStaticPaths() {
    let data = await fetch("http://localhost/umbraco/delivery/api/v2/content?filter=contentType:article");
    let articles = await data.json();
    
    return articles.items.map((article: any) => ({
        params: { slug: article.route.path },
        props: { article: article },
    }));
}

const { article } = Astro.props;
---

<Layout>
  <h1>{article.properties.title}</h1>
  <p>{article.properties.articleDate}</p>
  <div set:html={article.properties.content?.markup}></div>
</Layout>
```

你的项目现在应该包含以下文件：

<FileTree>
- src/
  - layouts/
    - Layout.astro
  - pages/
    - index.astro
    - **[...slug].astro**
</FileTree>

在开发服务器运行时，你现在应该能够在你的 Astro 项目的浏览器预览中查看由 Umbraco 创建的内容。恭喜你！🚀

## 发布你的网站

要部署你的网站，请访问我们的[部署指南](/zh-cn/guides/deploy/)并按照你选择的托管提供商的指示进行操作。

## 本地开发、HTTPS 和自签名 SSL 证书

如果你在本地使用 Umbraco 的 HTTPS 端点，任何 `fetch` 查询都会因为代码 `DEPTH_ZERO_SELF_SIGNED_CERT` 而导致 `fetch failed`。这是因为 Node（Astro 的基础）默认不接受自签名证书。为了避免这种情况，请在本地开发中使用 Umbraco 的 HTTP 端点。

或者，你可以在 `env.development` 文件中设置 `NODE_TLS_REJECT_UNAUTHORIZED=0` 并按如下方式更新 `astro.config.js`：

```ini title=".env.development"
NODE_TLS_REJECT_UNAUTHORIZED=0
```

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { loadEnv } from "vite";

const { NODE_TLS_REJECT_UNAUTHORIZED } = loadEnv(process.env.NODE_ENV, process.cwd(), "");
process.env.NODE_TLS_REJECT_UNAUTHORIZED = NODE_TLS_REJECT_UNAUTHORIZED;
// https://astro.build/config
export default defineConfig({});
```

此方法在这篇[博客文章](https://kjac.dev/posts/jamstack-for-free-with-azure-and-cloudflare/)中有更详细的描述，展示了如何为自签名证书配置你的项目，附带一个[相关的仓库](https://github.com/kjac/UmbracoAzureCloudflare)。

## 官方文档
- [Content Delivery API - Umbraco 文档](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api)

## 社区资源

- [使用 Content Delivery API 构建性能卓越的 Astro 网站 - Louis Richardson](https://24days.in/umbraco-cms/2023/sustainable-performant/astronomically-performant/)
- [从 Umbraco 的 Content Delivery API 生成 TypeScript OpenAPI 客户端 - Rick Butterfield](https://rickbutterfield.dev/blog/typescript-openapi-umbraco-content-delivery/)
- [使用 Azure 和 CloudFlare 免费构建 Jamstack - Kenn Jacobsen](https://kjac.dev/posts/jamstack-for-free-with-azure-and-cloudflare/)
- [使用 Astro 和 Umbraco 快速搭建博客 - Kenn Jacobsen](https://kjac.dev/posts/quick-n-dirty-blog-with-astro-and-umbraco/)
- [演讲：烘焙，但不油炸 - Astro 与 Content Delivery API - Adam Prendergast](https://www.youtube.com/watch?v=zNxqI25dtx4)
